// 版权所有2009 Go作者。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// go:build aix | darwin | drangfly | freebsd | | | | | jangfly | jangfly | freebsd | | | | | | | | | | | | | | | linux | | | | | | | | netbsd | | | | | | | |。

package poll

import (
	"io"
	"syscall"
)

func (fd *FD) eofError(n int, err error) error {
	if n == 0 && err == nil && fd.ZeroReadIsEOF {
		return io.EOF
	}
	return err
}

// Shutdown包装syscall.Shutdown。
func (fd *FD) Shutdown(how int) error {
	if err := fd.incref(); err != nil {
		return err
	}
	defer fd.decref()
	return syscall.Shutdown(fd.Sysfd, how)
}

// Fchown包装syscall.Fchown。
func (fd *FD) Fchown(uid, gid int) error {
	if err := fd.incref(); err != nil {
		return err
	}
	defer fd.decref()
	return ignoringEINTR(func() error {
		return syscall.Fchown(fd.Sysfd, uid, gid)
	})
}

// Ftruncate包装syscall.Ftruncate。
func (fd *FD) Ftruncate(size int64) error {
	if err := fd.incref(); err != nil {
		return err
	}
	defer fd.decref()
	return ignoringEINTR(func() error {
		return syscall.Ftruncate(fd.Sysfd, size)
	})
}

// RawControl为非IO 
// 操作调用用户定义的函数f。
func (fd *FD) RawControl(f func(uintptr)) error {
	if err := fd.incref(); err != nil {
		return err
	}
	defer fd.decref()
	f(uintptr(fd.Sysfd))
	return nil
}

// Ignoringeinter进行函数调用，如果返回
// EINTR错误，则重复该调用。尽管我们安装了所有带SA#U重启的
// 信号处理程序，但这似乎是必需的：请参阅#22838、#38033、#38836、#40846。
// 另外#20400和#36644是信号处理程序在未设置SA#U重启的情况下安装的问题。所有这些都不是常见的情况，但它们太多了，我们似乎无法避免一个EINTR循环。
func ignoringEINTR(fn func() error) error {
	for {
		err := fn()
		if err != syscall.EINTR {
			return err
		}
	}
}
